-- DungeonBossM
-- Created by chengb Mar/20/2015
-- 地牢BOSS模块

module("DungeonBossM", package.seeall);

-- 地牢BOSS配置表
local dungeonBossTable = {};

-- BOSS发言的随机数
local bossTalkRandom;

-- 内部函数
local whenStartDungeon;
local whenBossDied;

-- 载入配置表
local _init = false;
local loadCsv = function()
    if _init then return end
    _init = true;

    local dungeon_boss_CSV = get_dungeon_boss_CSV();
    for i = 1, #dungeon_boss_CSV do
        local id = dungeon_boss_CSV[i].id;
        dungeonBossTable[id] = dungeon_boss_CSV[i];
    end
end

-- 初始化
function init()
    loadCsv();

    -- 关注地牢开始的事件
    EventMgr.removeAll("DungeonBossM");
    EventMgr.register("DungeonBossM", event.START_DUNGEON, function(layer)
        whenStartDungeon();
    end);

    -- 注册BOSS死亡事件
    EventMgr.register("DungeonBossM", event.BOSS_DIE, function()
        whenBossDied();
    end);
end

-- 关注地牢开始的事件
function whenStartDungeon()
    -- 暂不做处理
end

-- 检索配置
function query(id, path)
    local m = dungeonBossTable[id];

    if not m or path == "" or not path then
        return m;
    end

    return m[path];
end

-- 获取boss格所在的位置
function getBossPos()
    if not isInBossLayer() then
        return -1;
    end

    local pos = query(DungeonM.getDungeonId(), "boss_grid");
    if type(pos) == "number" then
        return pos;
    end

    return -1;
end

---------------------
-- 是否是BOSS所在层
-- @param id    地牢id
-- @param layer 当前层
function isBossLayer(id, layer, user)
    -- 如果是在神龙夹层迷宫中
    if user and UnrealDungeonM.isInUnreal() then
        local unrealId = UnrealDungeonM.getUnrealId();
        local dbase = UnrealDungeonM.query(unrealId, "dbase");
        if dbase["is_boss"] == 1 then
            return true;
        else
            return false;
        end
    end

    -- 需要在夹层判断之后，否则非BOSS夹层会误判
    if FormulaM.invoke("IS_BOSS_LAYER", id, layer) then
        return true;
    end

    -- 如果是活动迷宫
    if ActivityDungeonM.isActivityDungeon(id) then
        -- 已经是最高层了
        local maxFloor = DungeonAreaM.query(id, "max_floor");
        if maxFloor == layer then
            return true;
        end
    end

    return false;
end

-- 是否在boss层
function isInBossLayer()
    if not DungeonM.isInDungeon() then
        return false;
    end

    local dungeonId = DungeonM.getDungeonId();
    local layer     = DungeonM.currentLayer();

    return isBossLayer(dungeonId, layer, ME.user);
end

-- 能否拾取目标
function canPickUpTarget()
    if not DungeonM.isAllMonsterDead() then
        -- 还有怪物没死
        return false;
    end

    return true;
end

-- 是否有奖励未领取
function haveBonus()
    if ActivityDungeonM.isInActivityBossLayer() then
        -- 活动副本BOSS层
        return ActivityDungeonM.haveBonus();
    end

    -- 获取所有格子
    local curDungeon = DungeonM.getCurrentDungeon();
    for _, grid in pairs(curDungeon) do
        -- boss宝箱
        if grid.type == GRID_TYPE_BOSS_BOX and
           grid.state ~= GRID_STATE_DISABLE then
           return true;
        end
        -- 活动boss宝箱
        if grid.type == GRID_TYPE_ACTIVITY_BOSS_BOX and
           grid.state ~= GRID_STATE_DISABLE then
           return true;
        end
    end

    return false;
end

-- 是否首次通关
function isFirstPass(dungeonId)
    if DungeonAreaM.query(dungeonId, "type") ~= "main" then
        return false;
    end

    local firstPass = ME.user.dbase:query("first_pass_boss", {});
    return firstPass[dungeonId] ~= 1;
end

-- boss死亡的回调
function whenBossDied()
    -- 如果不是在地牢内就忽略
    if not DungeonM.isInDungeon() then
        return;
    end

    local dungeonId = DungeonM.getDungeonId();
    local bgm = DungeonAreaM.query(dungeonId, "bg_music");

    -- boss死亡切换战斗音乐到背景音乐
    AudioM.playBgMusic(bgm);

    if DungeonAreaM.query(dungeonId, "type") ~= "main" then
        -- 首杀只考虑无尽模式
        return;
    end

    -- 如果是首杀，记录首杀，否则不管
    local firstPass = ME.user.dbase:query("first_pass_boss", {});
    if firstPass[dungeonId] == nil then
        firstPass[dungeonId] = 1;
        ME.user.dbase:set("first_pass_boss", firstPass);
    end
end

-- BOSS能否发言
function canBossTalk(ratio)
    -- 获取随机数
    local rand = getTalkRandom();
    if not rand then
        return false;
    end

    if rand > ratio then
        return false;
    end

    return true;
end

-- 获取BOSS发言的随机数
function getTalkRandom()
    return bossTalkRandom;
end

-- 设置BOSS发言的随机数
function setTalkRandom(num)
    bossTalkRandom = num and num or math.random(1000);
end
